/*
 * Copyright (C) 2010-2011 Graz University of Technology, Austria. All Rights reserved. 
 *
 * Contact: Simone Kopeinik <simone.kopeinik@tugraz.at>
 * 	   Graz University of Technology, Knowledge Management Institute, Brückenkopfgasse 1/6, 8020 Graz 	
 * 	   <http://www.kmi.tugraz.at/>
 * 
 * This software is part of the TARGET platform developed by the
 * TARGET EC-funded project www.reachyourtarget.org
 *
 * This software is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * The GNU General Public License is available at <http://www.gnu.org/licenses/>.
 *
 */
package at.tugraz.kmi.css.cbkst2.prereq.structurevis;

import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;

import org.apache.commons.collections15.Factory;

import at.tugraz.kmi.css.cbkst2.CbKSTCompetence;
import at.tugraz.kmi.css.cbkst2.PrerequesiteRelation;
import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.UndirectedGraph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.AbstractPopupGraphMousePlugin;
import edu.uci.ics.jung.visualization.picking.PickedState;

/**
 * a plugin that uses popup menus to create vertices, undirected edges, and
 * directed edges.
 * 
 * @author Tom Nelson
 * 
 */
final class CbKSTEditingPopupGraphMousePlugin extends
		AbstractPopupGraphMousePlugin {
	protected Factory<CbKSTCompetence>		vertexFactory;
	protected Factory<PrerequesiteRelation>	edgeFactory;
	protected JPopupMenu					popup	= new JPopupMenu();

	CbKSTEditingPopupGraphMousePlugin(Factory<CbKSTCompetence> vertexFactory,
			Factory<PrerequesiteRelation> edgeFactory) {
		this.vertexFactory = vertexFactory;
		this.edgeFactory = edgeFactory;
	}

	@Override
	@SuppressWarnings({ "unchecked", "serial" })
	protected void handlePopup(MouseEvent e) {
		final VisualizationViewer<CbKSTCompetence, PrerequesiteRelation> vv = (VisualizationViewer<CbKSTCompetence, PrerequesiteRelation>) e
				.getSource();
		final Layout<CbKSTCompetence, PrerequesiteRelation> layout = vv
				.getGraphLayout();
		final Graph<CbKSTCompetence, PrerequesiteRelation> graph = layout
				.getGraph();
		final Point2D p = e.getPoint();
		final Point2D ivp = p;
		GraphElementAccessor<CbKSTCompetence, PrerequesiteRelation> pickSupport = vv
				.getPickSupport();
		if (pickSupport != null) {

			final CbKSTCompetence vertex = pickSupport.getVertex(layout,
					ivp.getX(), ivp.getY());
			final PrerequesiteRelation edge = pickSupport.getEdge(layout,
					ivp.getX(), ivp.getY());
			final PickedState<CbKSTCompetence> pickedVertexState = vv
					.getPickedVertexState();
			final PickedState<PrerequesiteRelation> pickedEdgeState = vv
					.getPickedEdgeState();
			popup = new JPopupMenu();
			if (vertex != null) {
				Set<CbKSTCompetence> picked = pickedVertexState.getPicked();
				if (picked.size() > 0) {
					if (graph instanceof UndirectedGraph == false) {
						JMenu directedMenu = new JMenu("Create Directed Edge");
						popup.add(directedMenu);
						for (final CbKSTCompetence other : picked) {
							directedMenu.add(new AbstractAction("[" + other
									+ "," + vertex + "]") {
								@Override
								public void actionPerformed(ActionEvent e) {
									graph.addEdge(edgeFactory.create(), other,
											vertex, EdgeType.DIRECTED);
									vv.repaint();
								}
							});
						}
					}
					if (graph instanceof DirectedGraph == false) {
						JMenu undirectedMenu = new JMenu(
								"Create Undirected Edge");
						popup.add(undirectedMenu);
						for (final CbKSTCompetence other : picked) {
							undirectedMenu.add(new AbstractAction("[" + other
									+ "," + vertex + "]") {
								@Override
								public void actionPerformed(ActionEvent e) {
									graph.addEdge(edgeFactory.create(), other,
											vertex);
									vv.repaint();
								}
							});
						}
					}
				}
				popup.add(new AbstractAction("Delete Vertex") {
					@Override
					public void actionPerformed(ActionEvent e) {
						pickedVertexState.pick(vertex, false);
						graph.removeVertex(vertex);
						vv.repaint();
					}
				});
			} else if (edge != null) {
				popup.add(new AbstractAction("Delete Edge") {
					@Override
					public void actionPerformed(ActionEvent e) {
						pickedEdgeState.pick(edge, false);
						graph.removeEdge(edge);
						vv.repaint();
					}
				});
			}
			if (popup.getComponentCount() > 0) {
				popup.show(vv, e.getX(), e.getY());
			}
		}
	}
}
